<?php
require_once 'XPHP/Controller/Abstract.php';

/**
 * Lớp Front của Controller
 * @author Mr.UBKey
 * @package XPHP
 * @version Beta
 * @copyright XWEB
 */
class XPHP_Controller_Front extends XPHP_Controller_Abstract
{
	/**
	 * Chạy Front Controller
	 */
	public function dispatch()
	{
		//Xử lý Controller
		$class = "";
		//Nếu có area
		$area = $this->_router->getArea();
		if(!empty($area))
			$class .= $this->_router->getArea() . $this->_router->getAreaKey() . '_';
		
		$class .= $this->_router->getController() . $this->_router->getControllerKey();
		
		//Gọi tới action lấy giá trị trả về XPHP_View_Result_Interface
		$obj = new $class($this->_router);
		/*
		 * Gọi đến action đặc biệt
		 */
	 	//Nếu request là ajax request thì gọi tới actionAJAX và trả về kết quả
		if($obj->isAjaxRequest() && method_exists($class, $this->_router->getAction().'AJAX'))
		{
			$actionA = $this->_router->getAction().'AJAX';
			//Kiểm tra xem actionAJAX có định nghĩa kiểu dữ liệu cho model hay không ?
			$modelType = XPHP_Attribute::MethodAttributes($class, $actionA)->__get("model");
			if(!empty($modelType))
			{
				try {
					$model = new $modelType();
					$obj->setModel($model);
					$obj->parseModelParams();
				}
				catch(Exception $ex){
					require_once 'XPHP/Exception.php';
					throw new XPHP_Exception("Không tìm thấy lớp $modelType .");
				}
			}
			$result =  $obj->$actionA($this->_router->getArgs());
		}
		else 
		{
			//Nếu người dùng sử dụng form POST dữ liệu thì gọi tới actionPOST trước khi gọi action
			if(sizeof($_POST) > 0 && method_exists($class, $this->_router->getAction().'POST'))
			{
				$actionP = $this->_router->getAction().'POST';
				//Kiểm tra xem actionPOST có định nghĩa kiểu dữ liệu cho model hay không ?
				$modelType = XPHP_Attribute::MethodAttributes($class, $actionP)->__get("model");
				if(!empty($modelType))
				{
					try {
						$model = new $modelType();
						$obj->setModel($model);
						$obj->parseModelParams();
					}
					catch(Exception $ex){
						require_once 'XPHP/Exception.php';
						throw new XPHP_Exception("Không tìm thấy lớp $modelType .");
					}
				}
				//Gọi actionPOST
				$result = $obj->$actionP($this->_router->getArgs());
			}
			//Nếu người dùng sử dụng form GET để gửi dữ liệu thì gọi tới actionGET trước khi gọi action
			if(sizeof($_GET) > 1 && method_exists($class, $this->_router->getAction().'GET'))
			{
				$actionG = $this->_router->getAction().'GET';
				//Kiểm tra xem action có định nghĩa kiểu dữ liệu cho model hay không ?
				$modelType = XPHP_Attribute::MethodAttributes($class, $actionG)->__get("model");
				if(!empty($modelType))
				{
					try {
						$model = new $modelType();
						$obj->setModel($model);
						$obj->parseModelParams();
					}
					catch(Exception $ex){
						require_once 'XPHP/Exception.php';
						throw new XPHP_Exception("Không tìm thấy lớp $modelType .");
					}
				}
				//Gọi actionGET
				$result = $obj->$actionG($this->_router->getArgs());
			}
			
			$actionAC = $this->_router->getAction() . $this->_router->getActionKey();
			//Kiểm tra xem action có định nghĩa kiểu dữ liệu cho model hay không ?
			$modelType = XPHP_Attribute::MethodAttributes($class, $actionAC)->__get("model");
			if(!empty($modelType))
			{
				try {
					$model = new $modelType();
					$obj->setModel($model);
					$obj->parseModelParams();
				}
				catch(Exception $ex){
					require_once 'XPHP/Exception.php';
					throw new XPHP_Exception("Không tìm thấy lớp $modelType .");
				}
			}
			//Nếu POST và GET không trả về View_Result => Gọi action
			if(!isset($result))
		 		$result = $obj->$actionAC($this->_router->getArgs());
		}
		/*
		 * XỬ LÝ KẾT QUẢ TRẢ VỀ
		 */
		//Nếu kết quả trả về khác null
		if($result !== NULL)
		{
			//Xử lý View
			require_once 'XPHP/View.php';
			$view = new XPHP_View($this->_router);
			$view->setControllerResult($result);
			$view->setViewData($obj->view);
			$view->getLayout()->setLayoutFile($obj->getLayout());
			$view->setModel($obj->getModel());
			$view->ExecuteControllerResult();
		}
	}

}